package ocio.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import ocio.beans.Producto;
import ocio.beans.Provincia;
import ocio.beans.Subtipo;
import ocio.services.ProvinciaService;
import ocio.services.ServiceLocator;
import ocio.services.SubtipoService;

/**
 * Clase encargada de proporcionar listas cuyos valores pueden cambiar 
 * a lo largo de la sesión y otras funciones de utilidad.
 * @author Esther García Galán
 * @author Rubén Gómez Vales
 * @version 1.0 13/05/2014
 */
@SuppressWarnings("all")
public class RellenoCombos {

	private List<Provincia> listaProvincias = new ArrayList<Provincia>();
	private Set<String> listaMunicipios = new HashSet<String>();
	private List<Subtipo> listaSubtipos = new ArrayList<Subtipo>();
	private List<Integer> listaMeses = new ArrayList<Integer>();
	private Set<Integer> listaDias = new HashSet<Integer>();
	private List<Integer> listaAnios = new ArrayList<Integer>();
	private List<Integer> listaPlazas = new ArrayList<Integer>();
	
	public RellenoCombos(){
		
	}
		
	/**
	 * Devuelve una lista de provincias con o sin un valor que las represente a todas, para su uso en combos.
	 * @param sinTodas Indica si la lista de provincias debe contener un valor que las represente a todas.
	 * @return listaProvincias Lista de provincias.
	 */
	public List<Provincia> getListaProvincias (boolean sinTodas){ 
		ServiceLocator serviceLocator = ServiceLocator.getServiceLocator();
		ProvinciaService pS = (ProvinciaService)serviceLocator.getService("Provincia");		
		listaProvincias = pS.ListAllProvincias();
		if (sinTodas) listaProvincias.remove(0);		
		return listaProvincias;
	}
	
	/**
	 * Devuelve una lista de municipios que tienen algún evento en la BBDD 
	 * filtrando por provincia, tipo de evento y subtipo, para su uso en combos.
	 * @param idProvincia Provincia en la que se están buscando los municipios.
	 * @param tipo Tipo de producto que tiene que ofrecerse en el municipio
	 * @param idSubtipo Subtipo de producto que tiene que ofrecerse en el municipio.
	 * @return listaMunicipios Lista de municipios en los que hay disponibles eventos.
	 */
	public Set<String> getListaMunicipios(int idProvincia, String tipo, int idSubtipo){
		int tipoInt = this.getTipoInt(tipo);
		Producto producto = new Producto();
	
		ServiceLocator serviceLocator = ServiceLocator.getServiceLocator();
		
		// Se establece la provincia
		ProvinciaService provS = (ProvinciaService)serviceLocator.getService("Provincia");
		Provincia provincia = (Provincia) provS.searchById(idProvincia);
		producto.setProvincia(provincia);

		// Se establece el tipo. 
		producto.setTipo(tipoInt);
	
		//Se establece el producto
		if (idSubtipo!=0){
			SubtipoService sS = (SubtipoService)serviceLocator.getService("Subtipo");
			Subtipo subtipo = (Subtipo) sS.searchById(idSubtipo);
			producto.setSubtipo(subtipo);
		}
		
		// Se obtiene lista de productos que cumplen condiciones y se extraen sus municipios
		Iterator it = provincia.getProductos().iterator();
		 while(it.hasNext()) {
	         producto = (Producto) it.next();
	         if (producto.getTipo()==tipoInt){
	        	 if ((idSubtipo==0)||(producto.getSubtipo().getId()==idSubtipo)){
	       			 listaMunicipios.add(producto.getMunicipio());
	       		 } 
	         }
		 }		
		
		return listaMunicipios;
	}
	
	/**
	 * Devuelve una lista de subtipos correspondientes a un tipo dado, para su uso en combos.
	 * @param tipo Tipo de producto del que se buscan los subtipos.
	 * @return listaSubtipos Lista de subtipos correpondientes al tipo dado.
	 */
	public List<Subtipo> getListaSubtipos(String tipo){
		ServiceLocator serviceLocator = ServiceLocator.getServiceLocator();
		SubtipoService sS = (SubtipoService)serviceLocator.getService("Subtipo");
		
		
		Subtipo subtipo = new Subtipo();
		subtipo.setTipo(getTipoInt(tipo));
		Iterator it = sS.searchByFields(subtipo).iterator();
		 while(it.hasNext()) {
	         subtipo = (Subtipo) it.next();
	         listaSubtipos.add(subtipo);
		}
		 return listaSubtipos;
	}
	
	/**
	 * Devuelve un entero representando el tipo de producto a partir
	 * del literal Restaurante, Espectaculo o Actividad.
	 * @param tipo Tipo de producto en formato texto.
	 * @return tipoInt Valor entero que representa el tipo de producto.
	 */
	public int getTipoInt(String tipo){
		int tipoInt=0;
		if (tipo.equalsIgnoreCase("Restaurantes")){
			tipoInt=1;
			} else if (tipo.equalsIgnoreCase("Espectaculos")){
				tipoInt=2;
			}else{
				tipoInt=3;
		}
		return tipoInt;
	}
	
	/**
	 * Devuelve una lista de enteros que representan los meses del año para su uso en combos.
	 * @return listaMeses Lista de enteros representando los meses del año.
	 */
	public List<Integer> getListaMeses(){
		listaMeses = new ArrayList<Integer>();
			for (int i=1;i<13;i++){
				listaMeses.add(i);
			}
		return listaMeses;
	}
	
	/**
	 * Devuelve un objeto de tipo Date a partir de una fecha en formato Texto dd/MM/yyyy
	 * @param fecha Cadena de texto con una fecha.
	 * @return fechaDate Fecha en formato Date.
	 */
	public Date ParseFecha(String fecha)
	{
	    SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
	    Date fechaDate = null;
	    try {
	        fechaDate = formato.parse(fecha);
	    } 
	    catch (ParseException ex) 
	    {
	        System.out.println(ex);
	    }
	    return fechaDate;
	}


	public Set<Integer> getListaDias() {
		listaDias = new HashSet<Integer>();
		for (int i=1;i<32;i++){
			listaDias.add(i);
		}
		return listaDias;
	}

	public void setListaDias(Set<Integer> listaDias) {
		this.listaDias = listaDias;
	}

	/**
	 * Devuelve una lista de dos enteros que representan los dos próximos años, para su uso en combos.
	 * @return listaAnios Lista de enteros representando los dos próximos años.
	 */
	public List<Integer> getListaAnios() {
		Calendar c = new GregorianCalendar();
		int anio = (c.get(Calendar.YEAR));
		listaAnios.add(anio);listaAnios.add(anio+1);
		return listaAnios;
	}

	public void setListaAnios(List<Integer> listaAnios) {
		this.listaAnios = listaAnios;
	}


	public void setListaPlazas(List<Integer> listaPlazas) {
		this.listaPlazas = listaPlazas;
	}


}
